﻿namespace MongoDB.ConsoleClient
{
    using System;
    using System.IO;
    using System.Linq;
    using System.Text;

    using MongoDB.Data;
    using MongoDB.Driver;
    using MongoDB.Driver.Linq;
    using SupermarketSystem.MSSQLData;

    public class Client
    {
        public static void Main()
        {
            FromSqlToMongo();
            FromMongoToJSON();
        }

        public static void FromSqlToMongo()
        {
            using (var superMarketContext = new SupermarketSystemContext())
            {
                var productIDs = superMarketContext.ReportEntries.
                    Select(x => x.ProductID).Distinct();

                foreach (var id in productIDs)
                {
                    var productName = superMarketContext.Products.
                        Where(x => x.ProductID == id).Select(x => x.ProductName);
                    var vendorName = superMarketContext.Products.
                        Where(x => x.ProductID == id).Select(x => x.Vendor.VendorName);
                    var quantity = superMarketContext.ReportEntries.
                        Where(x => x.ProductID == id).Sum(x => x.Quantity);
                    var incomes = superMarketContext.ReportEntries.
                        Where(x => x.ProductID == id).Sum(x => x.Sum);

                    Product product = new Product() 
                    {
                        ProductId = id,
                        ProductName = productName.ToList()[0],
                        VendorName = vendorName.ToList()[0],
                        TotalQuantitySold = quantity,
                        TotalIncomes = incomes
                    };

                    SaveData<Product>(product);
                }
            }
        }

        public static void FromMongoToJSON()
        {
            var products = LoadData<Product>().ToList();

            foreach (var product in products)
            {
                StreamWriter writer = new StreamWriter(
                    @"..\..\..\..\Product-Reports\" + product.ProductId.ToString() + ".json");
                using (writer)
                {
                    StringBuilder sb = new StringBuilder();

                    sb.Append("{").AppendLine();
                    sb.AppendFormat("\tproduct-id: {0},", product.ProductId).AppendLine();
                    sb.AppendFormat("\tproduct-name: {0},", product.ProductName).AppendLine();
                    sb.AppendFormat("\tvendor-name: {0},", product.VendorName).AppendLine();
                    sb.AppendFormat("\ttotal-quantity-sold: {0},", product.TotalQuantitySold).AppendLine();
                    sb.AppendFormat("\ttotal-incomes: {0},", product.TotalIncomes).AppendLine();
                    sb.Append("}").AppendLine();

                    writer.WriteLine(sb);
                }
            }
        }

        private static void SaveData<T>(Product product)
        {
            try
            {
                MongoDBProvider.db.GetCollection<T>(typeof(T).Name).Save(product, SafeMode.True);
            }
            catch (MongoConnectionException)
            {
                throw new MongoCommandException("Cannot access database. Please try again later");
            }
        }

        private static IQueryable<T> LoadData<T>()
        {
            try
            {
                return MongoDBProvider.db.GetCollection<T>(typeof(T).Name).AsQueryable();
            }
            catch (MongoConnectionException ex)
            {
                throw new MongoCommandException("Cannot access database. Please try again later");
            }
        }
    }
}
